package jdk8;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public class MethodParameterReflection {

	public static void main(String[] args) {
		List<String> paramterNames = getParameterNameJava8(MethodParameterReflection.class, "getParameterNameJava8");
		paramterNames.forEach((x) -> System.out.println(x));
	}

	/**
	 * 方法的参数名，在很多时候我们是需要反射得到的。但是在java8之前，代码编译为class文件后，
	 * 方法参数的类型是固定的，但参数名称却丢失了，这和动态语言严重依赖参数名称形成了鲜明对比。
	 * （java是静态语言，所以入参名称叫什么其实无所谓的）。虽然名称无所谓，但很多时候，我们需
	 * 要此名称来做更好的安排，比如Myabtis的应用。
	 * 
	 * Java 8开始增加了类Parameter，在class文件中保留参数名，给反射带来了极大的便利。
	 * 
	 * 另外，能成功获取方法参数的名称需要满足两个条件：
	 * -> JDK版本必须是1.8及以上
	 * -> 编译时候必须有编译选项：javac -parameters打开，默认是关闭的
	 */
	public static List<String> getParameterNameJava8(Class<?> clazz, String methodName) {

		List<String> paramterList = new ArrayList<>();
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			if (methodName.equals(method.getName())) {
				// java8 新增方法 getParameters() 直接通过method就能拿到所有的参数
				Parameter[] params = method.getParameters();
				for (Parameter parameter : params) {
					paramterList.add(parameter.getType() + "  " + parameter.getName());
				}
			}
		}
		return paramterList;
	}
}